﻿using Universities;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using Moq;

namespace UniversityTests
{
    [TestClass]
    public class UniversityTest
    {
        [TestMethod]
        public void UniversityConstructorTest()
        {
            University target = new University();
        }

        [TestMethod]
        public void AddTest()
        {
            University target = new University();
            Student student = new Student("Marin", 61131);
            target.Add(student);
            Assert.IsTrue(target.Contains(student));
            Assert.IsTrue(target.Contains(student.Fn));
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void AddDuplicateStudentTest()
        {
            University target = new University();
            Student student = new Student("Marin", 61131);
            target.Add(student);
            target.Add(student);
        }

        [TestMethod]
        public void ContainsByFNTrueTest()
        {
            University target = new University();
            Student student = new Student("Marin", 61131);
            target.Add(student);
            int fn = 61131;
            bool expected = true;
            bool actual = target.Contains(fn);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void ContainsByFNFalseTest()
        {
            University target = new University();
            int fn = 61131;
            bool expected = false;
            bool actual = target.Contains(fn);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void ContainsStudentTrueTest()
        {
            University target = new University();
            Student student = new Student("Marin", 61131);
            target.Add(student);
            bool expected = true;
            bool actual = target.Contains(student);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void ContainsStudentFalseTest()
        {
            University target = new University();
            Student student = new Student("Marin", 61131);
            bool expected = false;
            bool actual = target.Contains(student);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void RemoveByFNTest()
        {
            University target = new University();
            Student student = new Student("Marin", 61131);
            target.Add(student);
            int fn = 61131;
            target.Remove(fn);
            bool expected = false;
            bool actual = target.Contains(fn);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void RemoveStudentTest()
        {
            University target = new University();
            Student student = new Student("Marin", 61131);
            target.Add(student);
            target.Remove(student);
            bool expected = false;
            bool actual = target.Contains(student);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void RemoveNonExistingStudentTest()
        {
            University target = new University();
            Student student = new Student("Marin", 61131);
            target.Remove(student);
        }

        private Dictionary<Student, List<double>> examResults = new Dictionary<Student, List<double>>();

        private void AddExamResults(Student student, string examName, double grade)
        {
            if (!examResults.ContainsKey(student))
            {
                examResults[student] = new List<double>();
            }
            examResults[student].Add(grade);
        }

        private IList<double> GetExamResults(Student student)
        {
            return examResults[student];
        }

        [TestMethod]
        public void AddExamResultsTest()
        {
            Mock<IExam> addExamResultsMock = new Mock<IExam>(MockBehavior.Strict);
            addExamResultsMock.Setup(x => x.AddExamResults(
                It.IsAny<Student>(), It.IsAny<string>(), It.IsInRange<double>(2, 6, Range.Inclusive)));
        }

        [TestMethod]
        public void GetExamResultsTest()
        {
            Mock<IExam> getExamResultsMock = new Mock<IExam>(MockBehavior.Strict);
            getExamResultsMock.Setup(x => x.GetExamResults(
                It.IsAny<Student>())).Returns((Student student) => { return GetExamResults(student); });
        }
    }
}
